﻿#include "ApMainWindow.h"

ApMainWindow::ApMainWindow(QWidget *parent)
	: QWidget(parent)
	, ui(new Ui::ApMainWindowClass())
{
	ui->setupUi(this);
	init();
}

ApMainWindow::~ApMainWindow()
{
	delete m_pThread;
	delete ui;
}

CN::TableSize ApMainWindow::getCurrentTableSize()
{
	switch (ui->comboBox->currentIndex())
	{
	case CN::Size16:
		return CN::Size16;

	case CN::Size24:
		return CN::Size24;

	case CN::Size32:
		return CN::Size32;

	case CN::Size48:
		return CN::Size48;
	}
}

int ApMainWindow::computeOffset(QString hzkStr)
{
	int offset = -1;
	int length;
	switch (ui->comboBox->currentIndex())
	{
	case CN::Size16:
		length = 32;
		break;

	case CN::Size24:
		length = 72;
		break;

	case CN::Size32:
		length = 128;
		break;

	case CN::Size48:
		length = 288;
		break;
	}
	QByteArray byteArray = hzkStr.toLocal8Bit();
	if (byteArray.size() >= 2) {
		uchar highByte = byteArray.at(0);
		uchar lowByte = byteArray.at(1);
		//qDebug() << QString("GB2312 Encoding of %1: 0x%2%3")
		//	.arg(hzkStr)
		//	.arg(highByte, 2, 16, QLatin1Char('0'))
		//	.arg(lowByte, 2, 16, QLatin1Char('0'));
		offset = (94 * (highByte - 0xA1) + (lowByte - 0xA1)) * length;
	}
	return offset;
}

void ApMainWindow::on_pushButton_show_clicked()
{
	QString chStr = ui->lineEdit_select->text();
	if (chStr == NULL)
	{
		qDebug() << "str is null...";
		return;
	}

	switch (ui->comboBox->currentIndex())
	{
	case 0:
		updateMat16(chStr);
		break;

	case 1:
		updateMat24(chStr);
		break;

	case CN::Size32:
		updateMat32(chStr);
		break;

	case CN::Size48:
		updateMat48(chStr);
		break;

	default:
		break;
	}
	
}

void ApMainWindow::on_pushButton_clear_clicked()
{
	switch (ui->comboBox->currentIndex())
	{
	case CN::Size16:
		m_mat16.setTo(0);
		
	case CN::Size24:
		m_mat24.setTo(0);

	case CN::Size32:
		m_mat32.setTo(0);

	case CN::Size48:
		m_mat48.setTo(0);

	default:
		break;
	}
	ui->tableWidget->clear();
}

void ApMainWindow::on_pushButton_edit_clicked()
{
	ui->comboBox->setEnabled(false);
	ui->spinBox->setEnabled(false);
	ui->lineEdit_select->setEnabled(false);
	ui->pushButton_edit->setEnabled(false);
	ui->pushButton_show->setEnabled(false);
	ui->pushButton_clear->setEnabled(false);

	ui->pushButton_quit->setEnabled(true);
	ui->pushButton_add->setEnabled(true);
	ui->pushButton_update->setEnabled(true);
	
	connect(ui->tableWidget, &QTableWidget::cellClicked, this, &ApMainWindow::shiftCellState);
	
}

void ApMainWindow::on_pushButton_quit_clicked()
{
	disconnect(ui->tableWidget, &QTableWidget::cellClicked, this, &ApMainWindow::shiftCellState);

	ui->comboBox->setEnabled(true);
	ui->spinBox->setEnabled(true);
	ui->lineEdit_select->setEnabled(true);
	ui->pushButton_edit->setEnabled(true);
	ui->pushButton_show->setEnabled(true);
	ui->pushButton_clear->setEnabled(true);

	ui->pushButton_quit->setEnabled(false);
	ui->pushButton_add->setEnabled(false);
	ui->pushButton_update->setEnabled(false);


}

void ApMainWindow::on_pushButton_update_clicked()
{
	switch (ui->comboBox->currentIndex())
	{
	case 0:
		writeMat16();
		QMessageBox::warning(this, "Tips", "修改HZK16成功！");
		break;

	case 1:
		writeMat24();
		QMessageBox::warning(this, "Tips", "修改HZK24成功！");
		break;

	case CN::Size32:
		writeMat32();
		QMessageBox::warning(this, "Tips", "修改HZK32成功！");
		break;

	case CN::Size48:
		writeMat48();
		QMessageBox::warning(this, "Tips", "修改HZK48成功！");
		break;

	}

}

void ApMainWindow::on_pushButton_add_clicked()
{
	m_offset = computeOffset(ui->lineEdit_add->text());
	switch (ui->comboBox->currentIndex())
	{
	case CN::Size16:
		writeMat16();
		QMessageBox::warning(this, "Tips", "添加HZK16成功！");
		break;

	case CN::Size24:
		writeMat24();
		QMessageBox::warning(this, "Tips", "添加HZK24成功！");
		break;

	case CN::Size32:
		writeMat32();
		QMessageBox::warning(this, "Tips", "添加HZK32成功！");
		break;

	case CN::Size48:
		writeMat48();
		QMessageBox::warning(this, "Tips", "添加HZK48成功！");
		break;
	}

	on_pushButton_quit_clicked();
}

void ApMainWindow::on_toolButton_clicked()
{
	switch (ui->comboBox->currentIndex())
	{
	case CN::Size16:
		m_filePath16 = QFileDialog::getOpenFileName(this, "请选择16×16的字库");
		ui->lineEdit_path->setText(m_filePath16);
		break;

	case CN::Size24:
		m_filePath24 = QFileDialog::getOpenFileName(this, "请选择24×24的字库");
		ui->lineEdit_path->setText(m_filePath24);
		break;

	case CN::Size32:
		m_filePath32 = QFileDialog::getOpenFileName(this, "请选择32×32的字库");
		ui->lineEdit_path->setText(m_filePath32);
		break;

	case CN::Size48:
		m_filePath48 = QFileDialog::getOpenFileName(this, "请选择48×48的字库");
		ui->lineEdit_path->setText(m_filePath48);
		break;

	default:
		break;
	}

}

void ApMainWindow::updatePixLength(int length)
{
	qDebug() << "PixLength:" << length;
	ui->tableWidget->horizontalHeader()->setDefaultSectionSize(length);
	ui->tableWidget->verticalHeader()->setDefaultSectionSize(length);
}

void ApMainWindow::shiftCellState(int x, int y)
{
	qDebug() << ui->comboBox->currentIndex();
	switch (ui->comboBox->currentIndex())
	{
	case 0:
		updateCellStateAndMat(x, y, m_mat16);
		break;

	case 1:
		updateCellStateAndMat(x, y, m_mat24);
		break;

	case CN::Size32:
		updateCellStateAndMat(x, y, m_mat32);
		break;

	case CN::Size48:
		updateCellStateAndMat(x, y, m_mat48);
		break;

	default:
		break;
	}

}

void ApMainWindow::shiftComboIndex(int index)
{
	switch (index)
	{
	case CN::Size16:
		ui->tableWidget->setColumnCount(16);
		ui->tableWidget->setRowCount(16);
		ui->lineEdit_path->setText(m_filePath16);
		m_mat16.setTo(0);
		break;

	case CN::Size24:
		ui->tableWidget->setColumnCount(24);
		ui->tableWidget->setRowCount(24);
		ui->lineEdit_path->setText(m_filePath24);
		m_mat24.setTo(0);
		break;

	case CN::Size32:
		ui->tableWidget->setColumnCount(32);
		ui->tableWidget->setRowCount(32);
		ui->lineEdit_path->setText(m_filePath32);
		m_mat32.setTo(0);
		break;

	case CN::Size48:
		ui->tableWidget->setColumnCount(48);
		ui->tableWidget->setRowCount(48);
		ui->lineEdit_path->setText(m_filePath48);
		m_mat48.setTo(0);
		break;

	default:
		break;
	}
}

void ApMainWindow::init()
{
	ui->tableWidget->setColumnCount(16);
	ui->tableWidget->setRowCount(16);

	ui->pushButton_quit->setEnabled(false);
	ui->pushButton_update->setEnabled(false);
	ui->pushButton_add->setEnabled(false);
	
	m_pThread = new AsThread(this);

	initMat();
}

void ApMainWindow::initMat()
{
	m_mat16 = cv::Mat::zeros(16, 16, CV_8UC1);
	m_mat24 = cv::Mat::zeros(24, 24, CV_8UC1);
	m_mat32 = cv::Mat::zeros(32, 32, CV_8UC1);
	m_mat48 = cv::Mat::zeros(48, 48, CV_8UC1);
}


void ApMainWindow::updateMat16(QString str)
{
	//QFile file("D:\\ChromeCoreDownloads\\font_library\\lib\\16x16\\hzk16s");
	QFile file(m_filePath16);
	if (!file.open(QIODevice::ReadOnly)) {
		qDebug() << "Failed to open HZK16 file.";
		return;
	}

	QByteArray byteArray = str.toLocal8Bit();
	if (byteArray.size() >= 2) {
		uchar highByte = byteArray.at(0);
		uchar lowByte = byteArray.at(1);
		qDebug() << QString("GB2312 Encoding of %1: 0x%2%3")
			.arg(str)
			.arg(highByte, 2, 16, QLatin1Char('0'))
			.arg(lowByte, 2, 16, QLatin1Char('0'));
		m_offset = (94 * (highByte - 0xA0 - 1) + (lowByte - 0xA0 - 1)) * 32;
	}

	file.seek(m_offset);
	qDebug() << QString("%1的偏移量为:").arg(str) << m_offset;
	QByteArray buffer = file.read(32);

	qDebug() << "Hex Bytes:";
	for (int k = 0; k < 32; k++) {
		qDebug() << QString("%1").arg((unsigned char)buffer[k], 2, 16, QChar('0'));
	}

	//qDebug() << "Pixel Data:";
	unsigned char key[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
	for (int k = 0; k < 16; k++) {
		//QString line;
		uchar *ptr = m_mat16.ptr<uchar>(k);
		for (int j = 0; j < 2; j++) {
			for (int i = 0; i < 8; i++) {
				unsigned char flag = buffer[k * 2 + j] & key[i];
				//line += flag ? "●" : "○";
				if (flag)
				{
					qDebug() << "k j i"<<k<<j<<i;
					ptr[8 * j + i] = 1;
					//QTableWidgetItem *item = ui->tableWidget->itemAt(k, 8 * j + i);
					//QTableWidgetItem *item = ui->tableWidget->itemAt( 8 * j + i, k);
					QTableWidgetItem *item = new QTableWidgetItem();
					item->setBackgroundColor(Qt::black);
					ui->tableWidget->setItem(k, 8 * j + i, item);
				}
			}
		}
		//qDebug() << line;
	}
	file.close();
}

//字库问题？
void ApMainWindow::updateMat24(QString str)
{
	//QFile file("D:\\ChromeCoreDownloads\\font_library\\lib\\24x24\\HZK24F");
	QFile file(m_filePath24);
	if (!file.open(QIODevice::ReadOnly)) {
		qDebug() << "Failed to open HZK24 file.";
		return;
	}

	QByteArray byteArray = str.toLocal8Bit();
	if (byteArray.size() >= 2) {
		uchar highByte = byteArray.at(0);
		uchar lowByte = byteArray.at(1);
		qDebug() << QString("GB2312 Encoding of %1: 0x%2%3")
			.arg(str)
			.arg(highByte, 2, 16, QLatin1Char('0'))
			.arg(lowByte, 2, 16, QLatin1Char('0'));
		m_offset = (94 * (highByte - 0xA1) + (lowByte - 0xA1)) * 72;
	}

	file.seek(m_offset);
	qDebug() << QString("%1的偏移量为:").arg(str) << m_offset;
	QByteArray buffer = file.read(72);

	qDebug() << "Hex Bytes:";
	for (int k = 0; k < 72; k++) {
		qDebug() << QString("%1").arg((unsigned char)buffer[k], 2, 16, QChar('0'));
	}

	//qDebug() << "Pixel Data:";
	for (int i = 0; i < 24; ++i) {
		for (int j = 0; j < 24; ++j) {
			int index = i * 3 + j / 8;
			int bit = 7 - j % 8;
			if (buffer[index] & (1 << bit)) {
				m_mat24.at<uchar>(j, i) = 1; // 设置为 1
				QTableWidgetItem *item = new QTableWidgetItem();
				item->setBackgroundColor(Qt::black);
				ui->tableWidget->setItem(j, i, item);
			}
		}
	}
	file.close();
}

void ApMainWindow::updateMat32(QString str)
{
	//QFile file("D:\\ChromeCoreDownloads\\font_library\\lib\\32x32\\HZK32");
	QFile file(m_filePath32);
	if (!file.open(QIODevice::ReadOnly)) {
		qDebug() << "Failed to open HZK32 file.";
		return;
	}

	QByteArray byteArray = str.toLocal8Bit();
	if (byteArray.size() >= 2) {
		uchar highByte = byteArray.at(0);
		uchar lowByte = byteArray.at(1);
		qDebug() << QString("GB2312 Encoding of %1: 0x%2%3")
			.arg(str)
			.arg(highByte, 2, 16, QLatin1Char('0'))
			.arg(lowByte, 2, 16, QLatin1Char('0'));
		m_offset = (94 * (highByte - 0xA1) + (lowByte - 0xA1)) * 128;
	}

	file.seek(m_offset);
	qDebug() << QString("%1的偏移量为:").arg(str) << m_offset;
	QByteArray buffer = file.read(128);

	qDebug() << "Hex Bytes:";
	for (int k = 0; k < 128; k++) {
		qDebug() << QString("%1").arg((unsigned char)buffer[k], 2, 16, QChar('0'));
	}

	//qDebug() << "Pixel Data:";
	for (int i = 0; i < 32; ++i) {
		for (int j = 0; j < 32; ++j) {
			int index = i * 4 + j / 8;
			int bit = 7 - j % 8;
			if (buffer[index] & (1 << bit)) {
				m_mat32.at<uchar>(i, j) = 1; // 设置为 1
				QTableWidgetItem *item = new QTableWidgetItem();
				item->setBackgroundColor(Qt::black);
				ui->tableWidget->setItem(i, j, item);
			}
		}
	}
	file.close();
}

void ApMainWindow::updateMat48(QString str)
{
	//QFile file("D:\\ChromeCoreDownloads\\font_library\\lib\\48x48\\HZK48S");
	QFile file(m_filePath48);
	if (!file.open(QIODevice::ReadOnly)) {
		qDebug() << "Failed to open HZK16 file.";
		return;
	}

	QByteArray byteArray = str.toLocal8Bit();
	if (byteArray.size() >= 2) {
		uchar highByte = byteArray.at(0);
		uchar lowByte = byteArray.at(1);
		qDebug() << QString("GB2312 Encoding of %1: 0x%2%3")
			.arg(str)
			.arg(highByte, 2, 16, QLatin1Char('0'))
			.arg(lowByte, 2, 16, QLatin1Char('0'));
		m_offset = (94 * (highByte - 0xA1) + (lowByte - 0xA1)) * 288;
	}

	file.seek(m_offset);
	qDebug() << QString("%1的偏移量为:").arg(str) << m_offset;
	QByteArray buffer = file.read(288);

	qDebug() << "Hex Bytes:";
	for (int k = 0; k < 288; k++) {
		qDebug() << QString("%1").arg((unsigned char)buffer[k], 2, 16, QChar('0'));
	}

	//qDebug() << "Pixel Data:";
	for (int i = 0; i < 48; ++i) {
		for (int j = 0; j < 48; ++j) {
			int index = i * 6 + j / 8;
			int bit = 7 - j % 8;
			if (buffer[index] & (1 << bit)) {
				m_mat48.at<uchar>(i, j) = 1; // 设置为 1
				QTableWidgetItem *item = new QTableWidgetItem();
				item->setBackgroundColor(Qt::black);
				ui->tableWidget->setItem(i, j, item);
			}
		}
	}
	file.close();
}

void ApMainWindow::writeMat16()
{
	//QFile file("D:\\ChromeCoreDownloads\\font_library\\lib\\16x16\\hzk16s");
	QFile file(m_filePath16);
	if (!file.open(QIODevice::ReadWrite)) {
		qDebug() << "Failed to open HZK16 file.";
		return;
	}

	QByteArray byteData;
	for (int row = 0; row < m_mat16.rows; row++)
	{
		uchar *ptr = m_mat16.ptr<uchar>(row);
		for (int j = 0; j < 2; j++)
		{
			QString binaryData;
			for (int i = 0; i < 8; i++)
			{
				binaryData += QString::number(ptr[j * 8 + i]);
			}
			bool ok;
			int byteValue = binaryData.toInt(&ok, 2);
			byteData.append(byteValue);
			qDebug() << binaryData.toLocal8Bit();
		}
	}

	qDebug() << "QByteArray.size：" << byteData.size();

	qDebug() << "此次偏移量为：" << m_offset;
	file.seek(m_offset);
	file.write(byteData, 32);
	file.close();
}

void ApMainWindow::writeMat24()
{
	//QFile file("D:\\ChromeCoreDownloads\\font_library\\lib\\24x24\\HZK24F");
	QFile file(m_filePath24);
	//QFile file("D:\\WeChat\\WeChat Files\\wxid_81c4t7ohbp1m22\\FileStorage\\File\\2023-08\\HZKf2424.hz");
	if (!file.open(QIODevice::ReadWrite)) {
		qDebug() << "Failed to open HZK24 file.";
		return;
	}

	QByteArray byteData;
	for (int col = 0; col < m_mat24.cols; col++)
	{
		for (int j = 0; j < 3; j++)
		{
			QString binaryData;
			for (int i = 0; i < 8; i++)
			{
				binaryData += QString::number(m_mat24.at<uchar>(j * 8 + i,col));
			}
			bool ok;
			int byteValue = binaryData.toInt(&ok, 2);
			byteData.append(byteValue);
			qDebug() << binaryData.toLocal8Bit();
		}
	}

	qDebug() << "QByteArray.size：" << byteData.size();

	qDebug() << "此次偏移量为：" << m_offset;
	file.seek(m_offset);
	qint64 ret = file.write(byteData, 72);
	qDebug() << "写入函数返回值:" << ret;
	file.close();

}

void ApMainWindow::writeMat32()
{
	//QFile file("D:\\ChromeCoreDownloads\\font_library\\lib\\32x32\\HZK32");
	QFile file(m_filePath32);
	if (!file.open(QIODevice::ReadWrite)) {
		qDebug() << "Failed to open HZK32 file.";
		return;
	}

	QByteArray byteData;
	for (int row = 0; row < m_mat32.rows; row++)
	{
		uchar *ptr = m_mat32.ptr<uchar>(row);
		for (int j = 0; j < 4; j++)
		{
			QString binaryData;
			for (int i = 0; i < 8; i++)
			{
				binaryData += QString::number(ptr[j * 8 + i]);
			}
			bool ok;
			int byteValue = binaryData.toInt(&ok, 2);
			byteData.append(byteValue);
			qDebug() << binaryData.toLocal8Bit();
		}
	}

	qDebug() << "QByteArray.size：" << byteData.size();

	qDebug() << "此次偏移量为：" << m_offset;
	file.seek(m_offset);
	file.write(byteData, 128);
	file.close();
}

void ApMainWindow::writeMat48()
{
	//QFile file("D:\\ChromeCoreDownloads\\font_library\\lib\\48x48\\HZK48S");
	QFile file(m_filePath48);
	if (!file.open(QIODevice::ReadWrite)) {
		qDebug() << "Failed to open HZK32 file.";
		return;
	}

	QByteArray byteData;
	for (int row = 0; row < m_mat48.rows; row++)
	{
		uchar *ptr = m_mat48.ptr<uchar>(row);
		for (int j = 0; j < 6; j++)
		{
			QString binaryData;
			for (int i = 0; i < 8; i++)
			{
				binaryData += QString::number(ptr[j * 8 + i]);
			}
			bool ok;
			int byteValue = binaryData.toInt(&ok, 2);
			byteData.append(byteValue);
			qDebug() << binaryData.toLocal8Bit();
		}
	}

	qDebug() << "QByteArray.size：" << byteData.size();

	qDebug() << "此次偏移量为：" << m_offset;
	file.seek(m_offset);
	file.write(byteData, 288);
	file.close();
}

void ApMainWindow::updateCellStateAndMat(int x, int y,cv::Mat &mat)
{
	if (mat.at<uchar>(x, y) == 0)
	{
		mat.at<uchar>(x, y) = 1;
		QTableWidgetItem *item = new QTableWidgetItem();
		item->setBackground(Qt::black);
		ui->tableWidget->setItem(x, y, item);
	}
	else
	{
		mat.at<uchar>(x, y) = 0;
		QTableWidgetItem *item = new QTableWidgetItem();
		item->setBackground(Qt::white);
		ui->tableWidget->setItem(x, y, item);
	}
}

